BYGGERIETS MACC-MODEL

Beregner, hvad det koster byggeriet at leve op til skærpede LCA-krav frem
mod 2030. Dækker fem bygningstyper (kontor, etageboliger, rækkehuse,
parcelhuse, øvrige) og årene 2026-2030. Alt måles i kg CO2e pr. m2 pr. år.


1. SÅDAN VIRKER MODELLEN

For hver kombination af bygningstype og bygningsdele
(fundamenter, etagedæk, indervægge, ydervægge, tage, vinduer) er der en
liste af løsninger. En løsning er en navngiven kombination af materialer,
for eksempel "grøn beton + grøn isolering + grønt stål". Hver løsning har en
pris i kr/m2 og en udledning i kg CO2e/m2.

Én løsning pr. bygningsdel er den konventionelle reference. Alt andet måles
op mod den.

Modellen vælger ikke bare den billigste løsning. Den fordeler
efterspørgslen ud over løsningerne efter, hvor tæt løsningerne ligger i pris,
så en løsning, der er lidt dyrere, stadig får en markedsandel. Andelene inden
for en bygningsdel summerer altid til én.

Hvor skarpt modellen skelner, styres af en spredningsparameter (se afsnit 5). En
lav værdi betyder, at næsten alle vælger den billigste; en høj værdi betyder,
at efterspørgslen fordeler sig bredt selv over mærkbare prisforskelle.

Hver bygningstype og hvert år har et emissionsloft. Modellen
finder den CO2-pris, hvor den valgte blanding af løsninger præcis rammer
loftet. Et strammere loft kræver en højere pris, da det flytter efterspørgslen
mod renere, men dyrere løsninger. Omkostningen ved den flytning er det, vi er
ude efter.

Ikke alle enkelte løsninger kan tage hele markedet. De fleste renere løsninger har en
maksimal andel, der vokser over tid, begrænset af et teknisk loft. Det er
det, der fx forhindrer modellen i at sætte alle kontorbyggerier på CLT i 2027.

Modellen løser først en baseline, hvor loftet er sat
lige under det, byggeriet når uden en CO2-pris. Derefter løser den igen én
gang pr. scenarie med de regulatoriske krav pålagt. Resultaterne rapporteres
som merudgiften i forhold til baseline.

2. FILER

    Abatement/
      run_abatement.py          kør modellen og lav figurer      
      abatement_main.gms        hovedfilen -- det er den, der køres, inkl definering af scenarier
      settings.gms              hvilke moduler der indlæses
      sets.gms                  sets: bygningstyper, år, scenarienavne
      functions.gms             hjælpefunktioner, bl.a. @solve

      Abatement.gms             selve modellen: variable, ligninger,
                                eksogene værdier, modelparametre
      Initialisation.gms        startværdier, prisgitter, baseline-loft
      Output.gms                outputvariable
      Site.gms                  valgfrit byggepladsmodul -- deaktiveret

      conopt.opt                solveroptioner -- den her læses
      conopt4.opt               identisk kopi

      MACC.gdx                  modellens datainput (genereres, se afsnit 7)
      

    Abatement/Data/
      stage0_load_macc.gms      importerer regnearket til MACC.gdx
      macc_timeseries_2026_2030.xlsx
                                modellens rådata, fremskrevet 2026-2030
      apply_growth_rates.R      laver fremskrivningen
      growth_parameters.csv     alle antagelser om udviklingen over tid
      base_macc_2026_scrambled.xlsx
                                priser og udledninger for 2026

    Abatement/Expanded/         udfoldet GAMS-kode, genereres ved kørsel
    Abatement/LST/              GAMS listing-filer
    Abatement/output/           resultater -- oprettes manuelt første gang


Skal du ændre noget, er det stort set altid én af tre filer:
abatement_main.gms for scenarier, Abatement.gms for modelparametre, og
Data/growth_parameters.csv for antagelser om udviklingen.

3. HVAD DER SKAL VÆRE INSTALLERET

  - GAMS, med CONOPT4 og en gyldig licens
  - Python 3.11 eller nyere, med dreamtools, gdxpds og pandas
  - Excel, GAMS kalder det for at læse regnearket
  - R 4.x med readxl, writexl og dplyr, hvis du vil ændre data

dreamtools finder projektet ved at lede efter paths.py opad i mappetræet,
så kør altid fra mappen Abatement.


4. SÅDAN KØRER DU MODELLEN

Kør linjerne i Run_abatement.py

Det tager 3-4 minutter. Hovedparten går til omkring 50 delproblemer, som
modellen løser for at kortlægge omkostningskurverne, før den gør noget andet.

Resultaterne ender i output, figurerne i output/md.

Vil du hellere køre fra en Python-konsol:

    from dreamtools.gamY import run
    run("abatement_main.gms")


5. SÅDAN ÆNDRER DU SCENARIERNE

Scenarierne står i abatement_main.gms. fra linje 159. 

Vil du ændre et krav, retter du tallet.Se eksempel:

    ScenarioTightening("A","etageboliger","2027") = 6.8;

C for 2029-2030 er ikke et politikscenarie: loftet er sat til det, modellen
teknisk kan levere, plus 0,01. 

Et nyt scenarie kræver to ting: navnet tilføjes sættet scen i sets.gms, og
lofterne tilføjes i abatement_main.gms som for A.


6. SÅDAN ÆNDRER DU MODELPARAMETRE

To parametre i Abatement.gms er værd at kende. 

Spredning i teknologivalget, linje 333:

    sig(b,s,i,ii)$sum(t,iActive(b,s,i,ii,t)) = 0.03;

Sætter hvor skarpt modellen skelner mellem løsninger på pris. Det er en
indflydelsesrig parameter i modellen: generelt kan lavere værdier skubbe efterspørgslen
over på de billigste løsninger og hæveomkostningen ved at opfylde et krav,
højere værdier spreder efterspørgslen og sænker den. Omkring de strengeste krav, 
kan der være udfald hvor sammenhængen er anderledes.

Udledninger uden virkemidler, linje 220:

Antagelser for hvordan emissioner i bygningsdele uden virkemidler kan anvendes, kan findes her. 
Vi anvender som udgangspunkt 1, hvor "oevrige" holdes fast, mens fx energiforbrug falder i forbindelse med lavere energiforbrug over tid. 


7. SÅDAN ÆNDRER DU DATA

Der er to steder, du kan ændre noget.

7.1 Antagelser om udviklingen over tid:

Data/growth_parameters.csv indeholder alle antagelser om, hvordan tingene
udvikler sig 2026-2030: EPD-forbedringer, prisfald på biogene materialer,
anvendelsespotentialer, tekniske lofter og risikopræmier. Hver linje har et
navn, en værdi og en beskrivelse.

Åbn den ikke i Excel, da det kan skabe problemer med semikolon.
Brug fx Notepad.

7.2 Priser og udledninger for de enkelte løsninger:

De ligger i Data/base_macc_2026_scrambled.xlsx. Én række pr. kombination af
bygningstype, bygningsdel, løsning og rådgivningsskridt, med enten en pris
eller en udledning i kolonnen value.

7.3 Efter en ændring: byg data om

Uanset hvilken af de to filer du har rettet, skal data bygges om i tre trin.
Modellen gør det ikke selv.

Trin 1: fremskriv til 2026-2030. Fra Abatement/Data:

    Rscript apply_growth_rates.R base_macc_2026_scrambled.xlsx
        growth_parameters.csv macc_timeseries_2026_2030.xlsx 2026 2030

Du kan også blot åbne apply_growth_rates.R i RStudio og køre hele filen.

Trin 2: importér regnearket til GAMS. Stadig fra Abatement/Data:

    gams stage0_load_macc.gms

Har du ændret antallet af rækker i regnearket, skal du først rette
rækkeintervallet i linje 71 af stage0_load_macc.gms

Trin 3: flyt datafilen op til modellen:

    Data/MACC.gdx .

Kør derefter modellen som i afsnit 3.


8. HVOR RESULTATERNE LIGGER

Alt havner i output. De to filer, du normalt skal bruge:

  - abatement_scenarios.gdx, omkostninger, udledninger og lofter for hvert
    scenarie, år og bygningstype
  - abatement_baseline.gdx, det samme for baseline, altså uden skærpede
    krav

Derudover er der tre filer til fejlsøgning: noTaxDebug.gdx (hvor loftet
binder, og hvor den tekniske grænse ligger), techdebug.gdx (hvilke løsninger
der vælges i hvert scenarie) og active_debug.gdx (priser og udledninger, som
modellen har læst dem).

Figurerne for hvert scenarie ligger i output/md.

GDX-filer kan åbnes i GAMS Studio eller læses i Python med gdxpds:

    import gdxpds
    df = gdxpds.to_dataframes("output/abatement_scenarios.gdx")
    print(df["CostTotScen"].head())

Vigtige outputs er: 
abatement_scenarios.gdx indeholder hovedresultaterne, alle med dimensionerne
scenarie, bygningstype og år:

  CostTotScen      omkostning i kr/m2 i scenariet
  CO2totScen       udledninger i kg CO2e/m2/år fra de dele, modellen kan
                   påvirke
  CapEmisScen      det loft, der faktisk var gældende
  CosttotBaseline  omkostning i kr/m2 i baseline, uden skærpede krav

abatement_baseline.gdx indeholder det samme for baseline, plus:

  pCO2             CO2-prisen, der skal til for at ramme loftet
  Share            markedsandelen for hver enkelt løsning
  EmisBaseline     referencebygningens udledninger fra de dele, modellen kan
                   påvirke
  emisNL           udledninger fra dele uden virkemidler
  fullBaselineCheck  EmisBaseline + emisNL, altså referencebygningen i alt

Resultatet er forskellen mellem scenariet og baseline:

  merudgift i kr/m2   = CostTotScen - CosttotBaseline
  merudgift i procent = CostTotScen / CosttotBaseline - 1

Det er den anden, figurerne viser. Niveauerne i sig selv skal bruges med
varsomhed: CostTot er modellens egen omkostningsopgørelse, ikke en byggepris,
der kan holdes op mod et faktisk budget. Det er forskellen mellem to kørsler,
der er meningsfuld, ikke niveauet.

CO2tot dækker kun de bygningsdele, hvor
modellen har virkemidler. De samlede udledninger er:

  CO2tot + emisNL = CapEmis

Loftet er altså på totalen, mens CO2tot er den del, der kan reduceres. 

Af samme grund er fullBaselineCheck i 2026 lig med 7,5 for kontor,
etageboliger og øvrige og 6,7 for parcel- og rækkehuse, altså præcis det
gældende krav. Det er ikke et resultat, men en kalibrering: residualposten er
sat, så det passer.

Der bliver automatisk lavet følgende figurer:

run_abatement.py laver to figurer pr. scenarie i output/md:

  CapEmisScen   det gældende loft over årene, pr. bygningstype
  CostRelScen   merudgiften i procent i forhold til baseline


9. VIDERE BRUG

I rapporten har vi anvendt resultaterne i GrønREFORM, for at få den samfundsøkonomiske effekt. 
Det er gjort ved at håndholdt anvende tre overordnede typer: By-boliger, Land-boliger og erhverv. 

I output-mappen er der gemt en Excel-fil 'Output til GR'.
Ved at indsætte abatementmodel outputs heri, beregnes der inputs som anvendt i GR.


10. HVIS NOGET GÅR I STYKKER

Stopper kørslen med "Error when solving", er det næsten altid en af tre ting:

  1. Et loft er strammere, end modellen kan nå. Slå maxAbateTotal op i
     output/noTaxDebug.gdx og lemp det pågældende krav.

  2. Data er ikke bygget om efter en ændring. Kør de tre trin i afsnit 6
     igen.

  3. I forbindelse med ændring af dataset kan det hjælpe af øge spredningsparameteren.
